package com.wlts.wzy.redisLockModule.config;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedisLocker  implements DistributedLocker{
 
    private final static String LOCKER_PREFIX = "lock:";
 
    @Autowired
    RedissonConnector redissonConnector;
    @Override
    public <T> T lock(String resourceName, AquiredLockWorker<T> worker) throws InterruptedException, UnableToAquireLockException, Exception {
 
        return lock(resourceName, worker, 100);
    }
 
    @Override
    public <T> T lock(String resourceName, AquiredLockWorker<T> worker, int lockTime) throws UnableToAquireLockException, Exception {
        RedissonClient redisson= redissonConnector.getClient();
        RLock lock = redisson.getLock(LOCKER_PREFIX + resourceName);
        // (公平锁)最多等待100秒，锁定后经过lockTime秒后自动解锁
        boolean success = lock.tryLock(100, lockTime, TimeUnit.SECONDS);

        System.out.println(success);

        if (success) {
            try {
                return worker.invokeAfterLockAquire();
            } finally {
                if(lock.isLocked()){
                    lock.unlock();
                }
            }
        }
        throw new UnableToAquireLockException();
    }

    @Override
    public <T> T lock(String resourceName, AquiredLockWorker<T> worker, int lockTime, int waitTime) throws UnableToAquireLockException, Exception {
        RedissonClient redisson= redissonConnector.getClient();
        RLock lock = redisson.getLock(LOCKER_PREFIX + resourceName);
        // (公平锁)最多等待waitTime秒，锁定后经过lockTime秒后自动解锁
        boolean success = lock.tryLock(waitTime, lockTime, TimeUnit.SECONDS);
        System.out.println(success);
        if (success) {
            try {
                return worker.invokeAfterLockAquire();
            } finally {
                lock.unlock();
            }
        }
        throw new UnableToAquireLockException();
    }


}